/*
 * W tej klasie po stronie klienta wygenerowane będą komunikaty "co się dzieje w walce",
 * przechowuje też klienckie wersje statystyk, które umożliwią odwzorowanie walki.
 * 
 * Konstruktor: na wejście wymaga stringa, który wygenerowała klasa Parser z metody parseFightData
 *              po stronie serwera, oraz obiektu PlayerStats, który powinien być utworzony po połączeniu się
 *              klienta z serwerem, po skończeniu pracy konstruktora, zapełnione będą wszystkie
 *              zadeklarowane wektory i inty
 * 
 * Jedyna metoda, którą powinniśmy wywoływać:
 * parseinfight - jako wejście wrzucamy string, który wygenerował serwer, po odbyciu się na nim akcji
 *                string jest postaci: ally/enemy+","+ally/enemy+","+command[0]+","+command[1]+","+command[2]+","+command[3]+","+nazwa czaru/przedmiotu+","+zmiana many postaci+","+zmiana:hp+","+mana+","+defence+","+attack+","+speed
 *                metoda edytuje wektory i inty, by odwzorować aktualny stan walki
 *              - wyjściem metody jest string, który można wpisać w log walki.
 *              - UWAGA: metoda nie precyzuje dla innej metody drukującej kto wykonał akcję, czy jaką wykonał,
 *                generuje tylko string do loga walki
 */
package wowmobileclient;

import java.util.Vector;

public class FightParser {

    private Vector playersnames;
    private Vector playershp;
    private Vector playersmaxhp;
    private Vector playersmana;
    private Vector playersmaxmana;
    private Vector enemiesnames;
    private Vector enemieshp;
    private Vector enemiesmaxhp;
    private Vector magics;
    private Vector items;
    private Vector playersimages;
    private Vector enemiesimages;
    private Vector magicsdescription;
    private Vector magicsimage;
    private Vector itemsdescription;
    private int defence;
    private int attack;
    private int speed;
    private int myid;
    private String nick;

    FightParser(String info, String nick) {
        this.playersnames = new Vector();
        this.playershp = new Vector();
        this.playersmaxhp = new Vector();
        this.playersmana = new Vector();
        this.playersmaxmana = new Vector();
        this.enemiesnames = new Vector();
        this.enemieshp = new Vector();
        this.enemiesmaxhp = new Vector();
        this.magics = new Vector();
        this.items = new Vector();
        this.playersimages = new Vector();
        this.enemiesimages = new Vector();
        this.magicsdescription = new Vector();
        this.magicsimage = new Vector();
        this.itemsdescription = new Vector();
        if (!info.equals("")) {
            String[] parsed = SplitString.split(info, ";");
            String[] tmp;
            for (int i = 0; i < parsed.length; i++) {
                tmp = SplitString.split(parsed[i], ",");
                parseprefight(tmp);
            }
        }
        this.myid = whoami();
    }

    private String interpreter(boolean playerastarget, int target, int manaown, int hp, int mana, int defence, int attack, int speed) {
        String name = "";
        String message = "";
        if (playerastarget) {
            name = ((String) playersnames.elementAt(target));
        } else {
            name = ((String) enemiesnames.elementAt(target));
        }
        if (manaown != 0) {
            message = " and used " + manaown + ", targetted " + name;
        } else {
            message = " and targetted " + name;
        }
        if (hp != 0) {
            if (hp < 0) {
                message += ", healed for " + (-hp);
            } else {
                message += ", damaged for " + hp;
            }
        }
        if (mana != 0) {
            if (mana < 0) {
                message += ", gave " + (-mana) + " mana";
            } else {
                message += ", took " + mana + " mana";
            }
        }
        if (defence != 0) {
            if (defence > 0) {
                message += ", buffed defence for " + defence;
            } else {
                message += ", debuffed defence for " + (-defence);
            }
            if (myid == target) {
                this.defence += defence;
            }
        }
        if (attack != 0) {
            if (attack > 0) {
                message += ", buffed defence for " + attack;
            } else {
                message += ", debuffed defence for " + (-attack);
            }
            if (myid == target) {
                this.defence += attack;
            }
        }
        if (speed != 0) {
            if (speed > 0) {
                message += ", buffed defence for " + speed;
            } else {
                message += ", debuffed defence for " + (-speed);
            }
            if (myid == target) {
                this.defence += speed;
            }
        }
        return message;
    }

    /*
    private boolean contains(String inwhat, char what) {
    for (int i = 0; i < inwhat.length(); i++) {
    if (inwhat.charAt(i) == what) {
    return true;
    }
    }
    return false;
    }
     */
    private int whoami() {
        return playersnames.indexOf(nick);
    }

//ally/enemy+","+ally/enemy+","+command[0]+","+command[1]+","+command[2]+","+command[3]+","+nazwa czaru/przedmiotu+","+zmiana many postaci+","+zmiana:hp+","+mana+","+defence+","+attack+","+speed
    public String parseinfight(String info) throws NumberFormatException {
        String statement = "";
        if (!info.equals("")) {
            String[] preparsed = SplitString.split(info, ";");

            String[] parsed = SplitString.split(preparsed[0], ",");
            /*if (parsed[6].equals("fail")) {
            if (parsed[0].equals("ally")) {
            if (parsed[3].equals("1")) {
            return playersnames.elementAt(Integer.parseInt(parsed[2]) - 1) + " failed at using magic.";
            } else if (parsed[3].equals("2")) {
            return playersnames.elementAt(Integer.parseInt(parsed[2]) - 1) + " failed at attacking.";
            } else {
            return playersnames.elementAt(Integer.parseInt(parsed[2]) - 1) + " failed at using item.";
            }
            } else {
            return "error, fail section";
            }
            } else*/
            if (parsed[3].equals("0")) {
                if (parsed[0].equals("ally")) {
                    statement = ((String) playersnames.elementAt(Integer.parseInt(parsed[2]) - 1)) + " is defending.";
                } else {
                    statement = ((String) enemiesnames.elementAt(Integer.parseInt(parsed[2]) - 1)) + " is defending.";
                }
            } else if (parsed[3].equals("7")) {
                if (parsed[4].equals("0")) {
                    return "error, can't meele attack all";
                } else if (parsed[4].equals("1")) {
                    if (parsed[0].equals("ally")) {
                        if (parsed[1].equals("ally")) {
                            changeMana(true, ((Integer.parseInt(parsed[2])) - 1), (Integer.parseInt(parsed[7])));
                            for (int i = 0; i < playersnames.capacity(); i++) {
                                changeHP(true, i, (Integer.parseInt(parsed[8])));
                                changeMana(true, i, (Integer.parseInt(parsed[9])));
                                statement = ((String) playersnames.elementAt(Integer.parseInt(parsed[2]) - 1)) + " used " + parsed[6]
                                        + interpreter(true, i, (Integer.parseInt(parsed[7])), (Integer.parseInt(parsed[8])), (Integer.parseInt(parsed[9])),
                                        (Integer.parseInt(parsed[10])), (Integer.parseInt(parsed[11])), (Integer.parseInt(parsed[12]))) + "/n";
                            }
                        } else {
                            enemieshp.removeAllElements();
                            parseprefight(SplitString.split(preparsed[1], ","));
                            changeMana(true, ((Integer.parseInt(parsed[2])) - 1), (Integer.parseInt(parsed[7])));
                            for (int i = 0; i < enemiesnames.capacity(); i++) {
                                changeHP(false, i, (Integer.parseInt(parsed[8])));
                                statement += ((String) playersnames.elementAt(Integer.parseInt(parsed[2]) - 1)) + " used " + parsed[6]
                                        + interpreter(false, i, (Integer.parseInt(parsed[7])), (Integer.parseInt(parsed[8])), (Integer.parseInt(parsed[9])),
                                        (Integer.parseInt(parsed[10])), (Integer.parseInt(parsed[11])), (Integer.parseInt(parsed[12]))) + "/n";
                            }
                        }
                    } else {
                        return "error, enemies can't use magics";
                    }
                } else if (parsed[4].equals("2")) {
                    return "error, items are usable on 1 player only";
                } else {
                    return "error, bad action";
                }
            } else {
                if (parsed[4].equals("0")) {
                    if (parsed[0].equals("ally")) {
                        int hptaken = Integer.parseInt((String) enemieshp.elementAt(Integer.parseInt(parsed[3]) - 1));
                        changeHP(false, (Integer.parseInt(parsed[3]) - 1), (Integer.parseInt(parsed[8])));
                        hptaken -= Integer.parseInt((String) enemieshp.elementAt(Integer.parseInt(parsed[3]) - 1));
                        statement = ((String) playersnames.elementAt(Integer.parseInt(parsed[2]) - 1)) + " attacked " + ((String) enemiesnames.elementAt(Integer.parseInt(parsed[3]) - 1)) + " for " + hptaken;
                    } else {
                        int hptaken = Integer.parseInt((String) playershp.elementAt(Integer.parseInt(parsed[3]) - 1));
                        changeHP(true, (Integer.parseInt(parsed[3]) - 1), (Integer.parseInt(parsed[8])));
                        hptaken -= Integer.parseInt((String) playershp.elementAt(Integer.parseInt(parsed[3]) - 1));
                        statement = ((String) enemiesnames.elementAt(Integer.parseInt(parsed[2]) - 1)) + " attacked " + ((String) playersnames.elementAt(Integer.parseInt(parsed[3]) - 1)) + " for " + hptaken;
                    }
                } else if (parsed[4].equals("1")) {
                    if (parsed[0].equals("ally")) {
                        if (parsed[1].equals("ally")) {
                            changeHP(true, (Integer.parseInt(parsed[3]) - 1), (Integer.parseInt(parsed[8])));
                            changeMana(true, ((Integer.parseInt(parsed[2])) - 1), (Integer.parseInt(parsed[7])));
                            changeMana(true, ((Integer.parseInt(parsed[3])) - 1), (Integer.parseInt(parsed[9])));
                            statement = ((String) playersnames.elementAt(Integer.parseInt(parsed[2]) - 1)) + " used " + parsed[6]
                                    + interpreter(true, (Integer.parseInt(parsed[3]) - 1), (Integer.parseInt(parsed[7])), (Integer.parseInt(parsed[8])), (Integer.parseInt(parsed[9])),
                                    (Integer.parseInt(parsed[10])), (Integer.parseInt(parsed[11])), (Integer.parseInt(parsed[12])));
                        } else {
                            changeHP(false, (Integer.parseInt(parsed[3]) - 1), (Integer.parseInt(parsed[8])));
                            changeMana(true, ((Integer.parseInt(parsed[2])) - 1), (Integer.parseInt(parsed[7])));
                            statement = ((String) playersnames.elementAt(Integer.parseInt(parsed[2]) - 1)) + " used " + parsed[6]
                                    + interpreter(false, (Integer.parseInt(parsed[3]) - 1), (Integer.parseInt(parsed[7])), (Integer.parseInt(parsed[8])), (Integer.parseInt(parsed[9])),
                                    (Integer.parseInt(parsed[10])), (Integer.parseInt(parsed[11])), (Integer.parseInt(parsed[12])));
                        }
                    } else {
                        return "error, enemies can't use magics";
                    }
                } else if (parsed[4].equals("2")) {
                    if (parsed[0].equals("ally")) {
                        if (parsed[1].equals("ally")) {
                            changeMana(true, ((Integer.parseInt(parsed[2])) - 1), (Integer.parseInt(parsed[7])));
                            for (int i = 0; i < playersnames.capacity(); i++) {
                                changeHP(true, i, (Integer.parseInt(parsed[8])));
                                changeMana(true, i, (Integer.parseInt(parsed[9])));
                                statement = ((String) playersnames.elementAt(Integer.parseInt(parsed[2]) - 1)) + " used " + parsed[6]
                                        + interpreter(true, i, (Integer.parseInt(parsed[7])), (Integer.parseInt(parsed[8])), (Integer.parseInt(parsed[9])),
                                        (Integer.parseInt(parsed[10])), (Integer.parseInt(parsed[11])), (Integer.parseInt(parsed[12]))) + "/n";
                            }
                        } else {
                            return "error, can't use items on enemies";
                        }
                    } else {
                        return "error, enemies can't use items";
                    }
                } else {
                    return "error, bad action";
                }
            }
        }

        return statement;
    }

    private void parseprefight(String[] partofparsed) {

        if (partofparsed[0].equals("PlayersNames")) {
            for (int i = 1; i < partofparsed.length; i++) {
                playersnames.addElement(partofparsed[i]);
            }
        } else if (partofparsed[0].equals("PlayersHp")) {
            for (int i = 1; i < partofparsed.length; i++) {
                playershp.addElement(partofparsed[i]);
            }
        } else if (partofparsed[0].equals("PlayersMaxHp")) {
            for (int i = 1; i < partofparsed.length; i++) {
                playersmaxhp.addElement(partofparsed[i]);
            }
        } else if (partofparsed[0].equals("PlayersMana")) {
            for (int i = 1; i < partofparsed.length; i++) {
                playersmana.addElement(partofparsed[i]);
            }
        } else if (partofparsed[0].equals("PlayersMaxMana")) {
            for (int i = 1; i < partofparsed.length; i++) {
                playersmaxmana.addElement(partofparsed[i]);
            }
        } else if (partofparsed[0].equals("EnemiesNames")) {
            for (int i = 1; i < partofparsed.length; i++) {
                enemiesnames.addElement(partofparsed[i]);
            }
        } else if (partofparsed[0].equals("EnemiesHp")) {
            for (int i = 1; i < partofparsed.length; i++) {
                enemieshp.addElement(partofparsed[i]);
            }
        } else if (partofparsed[0].equals("EnemiesMaxHp")) {
            for (int i = 1; i < partofparsed.length; i++) {
                enemiesmaxhp.addElement(partofparsed[i]);
            }
        } else if (partofparsed[0].equals("Magics")) {
            for (int i = 1; i < partofparsed.length; i++) {
                magics.addElement(partofparsed[i]);
            }
        } else if (partofparsed[0].equals("MagicsDescriptions")) {
            for (int i = 1; i < partofparsed.length; i++) {
                magicsdescription.addElement(partofparsed[i]);
            }
        } else if (partofparsed[0].equals("MagicsImage")) {
            for (int i = 1; i < partofparsed.length; i++) {
                magicsimage.addElement(partofparsed[i]);
            }
        } else if (partofparsed[0].equals("Items")) {
            for (int i = 1; i < partofparsed.length; i++) {
                items.addElement(partofparsed[i]);
            }
        } else if (partofparsed[0].equals("ItemsDescriptions")) {
            for (int i = 1; i < partofparsed.length; i++) {
                itemsdescription.addElement(partofparsed[i]);
            }
        } else if (partofparsed[0].equals("PlayersImages")) {
            for (int i = 1; i < partofparsed.length; i++) {
                playersimages.addElement(partofparsed[i]);
            }
        } else if (partofparsed[0].equals("EnemiesImages")) {
            for (int i = 1; i < partofparsed.length; i++) {
                enemiesimages.addElement(partofparsed[i]);
            }
        } else if (partofparsed[0].equals("Defence")) {
            this.defence = Integer.parseInt(partofparsed[1]);
        } else if (partofparsed[0].equals("Attack")) {
            this.attack = Integer.parseInt(partofparsed[1]);
        } else if (partofparsed[0].equals("Speed")) {
            this.speed = Integer.parseInt(partofparsed[1]);
        } else {
            //wtf?!
        }
    }

    public void changeMana(boolean isplayer, int id, int amount) throws NumberFormatException {
        int mana = 0;
        int maxmana = 0;
        if (isplayer) {
            mana = Integer.parseInt((String) playersmana.elementAt(id));
            maxmana = Integer.parseInt((String) playersmaxmana.elementAt(id));
            if (amount < 0) {
                if (mana - amount <= maxmana) {
                    playersmana.setElementAt(Integer.toString(mana - amount), id);
                } else {
                    playersmana.setElementAt(Integer.toString(maxmana), id);
                }
            } else {
                if (mana - amount >= 0) {
                    playersmana.setElementAt(Integer.toString(mana - amount), id);
                } else {
                    playersmana.setElementAt(Integer.toString(0), id);
                }
            }
        } else {
            //void
        }
    }

    public void changeHP(boolean isplayer, int id, int amount) throws NumberFormatException {
        int hp = 0;
        int maxhp = 0;
        if (isplayer) {
            hp = Integer.parseInt((String) playershp.elementAt(id));
            maxhp = Integer.parseInt((String) playersmaxhp.elementAt(id));
            if (amount < 0) {
                if (hp - amount <= maxhp) {
                    playershp.setElementAt(Integer.toString(hp - amount), id);
                } else {
                    playershp.setElementAt(Integer.toString(maxhp), id);
                }
            } else {
                if (hp - amount >= 0) {
                    playershp.setElementAt(Integer.toString(hp - amount), id);
                } else {
                    playershp.setElementAt(Integer.toString(0), id);
                }
            }
        } else {
            hp = Integer.parseInt((String) enemieshp.elementAt(id));
            maxhp = Integer.parseInt((String) enemiesmaxhp.elementAt(id));
            if (amount < 0) {
                if (hp - amount <= maxhp) {
                    enemieshp.setElementAt(Integer.toString(hp - amount), id);
                } else {
                    enemieshp.setElementAt(Integer.toString(maxhp), id);
                }
            } else {
                if (hp - amount >= 0) {
                    enemieshp.setElementAt(Integer.toString(hp - amount), id);
                } else {
                    enemieshp.setElementAt(Integer.toString(0), id);
                }
            }
        }
    }

    public Vector getEnemiesimages() {
        return enemiesimages;
    }

    public Vector getEnemiesmaxhp() {
        return enemiesmaxhp;
    }

    public int getMyid() {
        return myid;
    }

    public Vector getPlayersimages() {
        return playersimages;
    }

    public Vector getPlayersmaxhp() {
        return playersmaxhp;
    }

    public Vector getPlayersmaxmana() {
        return playersmaxmana;
    }

    public int getDefence() {
        return defence;
    }

    public Vector getEnemieshp() {
        return enemieshp;
    }

    public Vector getEnemiesnames() {
        return enemiesnames;
    }

    public Vector getItems() {
        return items;
    }

    public Vector getMagics() {
        return magics;
    }

    public Vector getPlayershp() {
        return playershp;
    }

    public Vector getPlayersmana() {
        return playersmana;
    }

    public Vector getPlayersnames() {
        return playersnames;
    }

    public int getAttack() {
        return attack;
    }

    public int getSpeed() {
        return speed;
    }

    public Vector getItemsdescription() {
        return itemsdescription;
    }

    public Vector getMagicsdescription() {
        return magicsdescription;
    }

    public Vector getMagicsimage() {
        return magicsimage;
    }
}
